package com.lemurian.bankdata.bean;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import com.lemurian.bankdata.bean.base.BaseDaoHibernate;
import com.lemurian.bankdata.lite.logger.BankDataLogger;
import com.lemurian.bankdata.lite.struts.PartialList;
import com.lemurian.bankdata.report.dto.PengecekanSertifikat;
import com.lemurian.entity.Category;
import com.lemurian.entity.Client;
import com.lemurian.entity.SignatureSchedule;

@Repository
public class SignatureScheduleDAO extends BaseDaoHibernate<SignatureSchedule>{
	
	private BankDataLogger log = BankDataLogger.getLogger(SignatureScheduleDAO.class.getName());

	@Override
	public SignatureSchedule findById(int id) {
		log.info("Overide findById on SignatureScheduleDAO, Get in");
		try {
			Criteria criteria = sessionFactory.getCurrentSession().createCriteria(SignatureSchedule.class);
			criteria.createAlias("client", "client");
			criteria.createAlias("client.debitur", "debitur");
			
			criteria.add(Restrictions.eq("id", id));
			return (SignatureSchedule) criteria.uniqueResult();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	
	public PartialList<SignatureSchedule> findSchedule(int start, int count, Order order, Criterion... criterion){
		PartialList<SignatureSchedule> partialList = null;
		try {
			log.info("Get in findSchedule :)");
			
			// total
			Criteria criteria = sessionFactory.getCurrentSession().createCriteria(SignatureSchedule.class);
			criteria.createAlias("client", "client");
			criteria.createAlias("client.debitur", "debitur");
			criteria.createAlias("department", "department");
			criteria.createAlias("client.clientCertificates", "clientCertificates", CriteriaSpecification.LEFT_JOIN);//.setFetchMode(ClientCertificate.class, FetchMode.JOIN);
			criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
			criteria.setCacheable(true);
			
			for (Criterion c : criterion) {
				criteria.add(c);
			}
			criteria.setProjection(Projections.rowCount());
			int total = ((Integer) criteria.list().iterator().next()).intValue();
			// partial data
			criteria = sessionFactory.getCurrentSession().createCriteria(SignatureSchedule.class);
			criteria.createAlias("client", "client");
			criteria.createAlias("client.debitur", "debitur");
			criteria.createAlias("department", "department");
			criteria.createAlias("client.clientCertificates", "clientCertificates", CriteriaSpecification.LEFT_JOIN);
			criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

			criteria.setCacheable(true);
			
			for (Criterion c : criterion) {
				System.out.println("crit : " + c.toString());
				criteria.add(c);
			}
			if (order!=null) criteria.addOrder(order);
			criteria.setFirstResult(start);
			criteria.setMaxResults(count);
			
			partialList = new PartialList<SignatureSchedule>(criteria.list(), total);
		} catch(Exception exception){
			exception.printStackTrace();
			//sessionFactory.getCurrentSession().getTransaction().rollback();
		}
		return partialList;
	}


	public PartialList<SignatureSchedule> findClientForKepengurusan(int start, int count, Order order, Criterion... criterion) {
		PartialList<SignatureSchedule> partialList = null;
		try {
			log.info("Get in findClientForKepengurusan");
			
			// total
			Criteria criteria = sessionFactory.getCurrentSession().createCriteria(SignatureSchedule.class);
			criteria.createAlias("client", "client");
			criteria.createAlias("client.debitur", "debitur");
			criteria.createAlias("client.accountOfficer", "client.accountOfficer");
						
			criteria.setCacheable(true);
			
			for (Criterion c : criterion) {
				criteria.add(c);
			}
			criteria.setProjection(Projections.rowCount());
			int total = ((Integer) criteria.list().iterator().next()).intValue();
			// partial data
			criteria = sessionFactory.getCurrentSession().createCriteria(SignatureSchedule.class);
			criteria.createAlias("client", "client");
			criteria.createAlias("client.debitur", "debitur");
			criteria.createAlias("client.accountOfficer", "accountOfficer");

			criteria.setCacheable(true);
			
			for (Criterion c : criterion) {
				System.out.println("crit : " + c.toString());
				criteria.add(c);
			}
			if (order!=null) criteria.addOrder(order);
			criteria.setFirstResult(start);
			criteria.setMaxResults(count);
			
			partialList = new PartialList<SignatureSchedule>(criteria.list(), total);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return partialList;
	}
	
	public SignatureSchedule findSignatureScheduleByClient(Client client) {
		try {
			Criteria criteria = sessionFactory.getCurrentSession().createCriteria(SignatureSchedule.class);
			criteria.createAlias("client", "client");
			criteria.createCriteria("client.debitur", "debitur");
			
			criteria.add(Restrictions.eq("client", client));
			
			SignatureSchedule signatureSchedule = (SignatureSchedule) criteria.uniqueResult();
			if (signatureSchedule != null) {
				return signatureSchedule;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return new SignatureSchedule();
	}

	public SignatureSchedule findScheduleByClientAndDepartment(Client client, Category department) {
		try {
			Criteria criteria = sessionFactory.getCurrentSession().createCriteria(SignatureSchedule.class);
			criteria.createAlias("client", "client");
			criteria.createCriteria("client.debitur", "debitur");
			criteria.createCriteria("department", "department");
			
			criteria.add(Restrictions.eq("client", client));
			criteria.add(Restrictions.eq("department", department));
			
			SignatureSchedule signatureSchedule = (SignatureSchedule) criteria.uniqueResult();
			if (signatureSchedule != null) {
				return signatureSchedule;
			}	
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public List<PengecekanSertifikat> pdfReport(String namaSertifikat, String wilayah, String kodeUrusan) {
		List<PengecekanSertifikat> list = null;
		
		try {
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return list;
	}
	
	public Criteria initializeCriteria (String namaSertifikat, String wilayah, String kodeUrusan) {
		Criteria criteria = getSession().createCriteria(SignatureSchedule.class);
		
		criteria.setCacheable(Boolean.TRUE);
		criteria.createAlias("client", "client");
		criteria.createAlias("client.debitur", "debitur");
		
		if(namaSertifikat != null && namaSertifikat.length() > 0) {
			criteria.add(Restrictions.ilike("certificate.name", namaSertifikat, MatchMode.ANYWHERE));
		}
		
		if(wilayah != null && wilayah.length() > 0) {
			criteria.add(Restrictions.ilike("certificate.reqion", wilayah , MatchMode.ANYWHERE));
		}
		
		if(kodeUrusan != null && kodeUrusan.length() > 0) {
			criteria.add(Restrictions.ilike("certificate.reqion", wilayah , MatchMode.ANYWHERE));
		}
		
		return criteria;
	}	
}